/*
 * \brief   Pistachio thread facility
 * \author  Christian Helmuth
 * \date    2006-04-11
 */

/*
 * Copyright (C) 2006-2009 Christian Helmuth
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#ifndef _CORE__INCLUDE__PLATFORM_THREAD_H_
#define _CORE__INCLUDE__PLATFORM_THREAD_H_

#include <thread/capability.h>
#include <base/thread_state.h>

#include <platform_pd.h>

namespace Pistachio {
#include <l4/types.h>
}

namespace Genode {

	class Platform_pd;
	class Platform_thread
	{
		private:

			int                      _thread_id;      /* plain thread number */
			Pistachio::L4_ThreadId_t _l4_thread_id;   /* L4 thread ID */
			char                     _name[32];       /* thread name that will be
			                                             registered at the kernel
			                                             debugger */
			Platform_pd             *_platform_pd;    /* protection domain thread
			                                             is bound to */

		protected:

			Capability               _pager_cap;      /* pager capability */

		public:

			enum {
				THREAD_INVALID = -1,  /* invalid thread number */
			};

			/**
			 * Constructor
			 */
			Platform_thread(const char *name = 0, int thread_id = THREAD_INVALID);

			/**
			 * Destructor
			 */
			~Platform_thread();

			/**
			 * Start thread
			 *
			 * \param ip      instruction poiner to start at
			 * \param sp      stack pointer tu use
			 * \param cpu_no  target cpu
			 *
			 * \retval  0  successful
			 * \retval -1  thread could not be started
			 */
			int start(void *ip, void *sp, unsigned int cpu_no = 0);

			/**
			 * Cancel currently blocking operation
			 */
			void cancel_blocking();

			/**
			 * This thread is about to be bound
			 *
			 * \param thread_id     local thread ID
			 * \param l4_thread_id  final L4 thread ID
			 * \param pd            platform pd, thread is bound to
			 */
			void bind(int thread_id, Pistachio::L4_ThreadId_t l4_thread_id,
			          Platform_pd *pd);

			/**
			 * Unbind this thread
			 */
			void unbind();

			/**
			 * Request thread state
			 *
			 * \param  state_dst  destination state buffer
			 *
			 * \retval  0 successful
			 * \retval -1 thread state not accessible
			 */
			int state(Genode::Thread_state *state_dst);


			/************************
			 ** Accessor functions **
			 ************************/

			/**
			 * Return/set pager capability
			 */
			inline Capability pager_cap() const { return _pager_cap; }
			inline void pager_cap(Thread_capability pager) { _pager_cap = pager; }

			/**
			 * Set the executing CPU for this thread.
			 */
			void set_cpu(unsigned int cpu_no);


			/**********************************
			 ** Pistachio-specific Accessors **
			 **********************************/

			inline int                       thread_id()    const { return _thread_id; }
			inline Pistachio::L4_ThreadId_t  l4_thread_id() const { return _l4_thread_id; }
			inline const char               *name()         const { return _name; }

			/* use only for core... */
			inline void set_l4_thread_id(Pistachio::L4_ThreadId_t id) {
				_l4_thread_id = id; }
	};
}

#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
